package cuongnh.project.japanesediary.vocabulary.common;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.NotEnabledException;
import org.eclipse.core.commands.NotHandledException;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.services.IEvaluationService;

import cuongnh.project.japanesediary.vocabulary.model.Grammar;
import cuongnh.project.japanesediary.vocabulary.model.Kanji;
import cuongnh.project.japanesediary.vocabulary.model.Sentence;
import cuongnh.project.japanesediary.vocabulary.model.Vocabulary;
import cuongnh.project.japanesediary.vocabulary.ui.editor.grammar.GrammarEditor;
import cuongnh.project.japanesediary.vocabulary.ui.editor.grammar.GrammarEditorInput;
import cuongnh.project.japanesediary.vocabulary.ui.editor.kanji.KanjiEditor;
import cuongnh.project.japanesediary.vocabulary.ui.editor.kanji.KanjiEditorInput;
import cuongnh.project.japanesediary.vocabulary.ui.editor.vocabulary.VocabularyEditor;
import cuongnh.project.japanesediary.vocabulary.ui.editor.vocabulary.VocabularyEditorInput;
import cuongnh.project.japanesediary.vocabulary.ui.handler.command.NewVocabulary;
import cuongnh.project.japanesediary.vocabulary.ui.wizard.AddSentenceWizard;

public class CommonUtils {
	public static final String EMPTY_STRING = "";

	public static final int TABLE_ROW_HEIGH_DEFAULT = 20;

	public static void vocabulariesHookDoubleClickCommand(
			final TableViewer tableViewer) {
		tableViewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				try {
					IStructuredSelection selection = (IStructuredSelection) tableViewer
							.getSelection();
					Vocabulary vocabulary = (Vocabulary) selection
							.getFirstElement();
					IWorkbenchPage page = PlatformUI.getWorkbench()
							.getActiveWorkbenchWindow().getActivePage();
					VocabularyEditorInput input = new VocabularyEditorInput(
							vocabulary.getVocabularyId());
					IEditorPart editor = page.findEditor(input);
					if (editor != null && editor instanceof VocabularyEditor) {
						page.activate(editor);
					} else {
						page.openEditor(input, VocabularyEditor.ID);
					}

				} catch (Exception ex) {
					throw new RuntimeException(VocabularyEditor.ID);
				}
			}
		});
	}

	public static void kanjisHookDoubleClickCommand(
			final TableViewer tableViewer) {
		tableViewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				try {
					IStructuredSelection selection = (IStructuredSelection) tableViewer
							.getSelection();
					Kanji kanji = (Kanji) selection.getFirstElement();
					IWorkbenchPage page = PlatformUI.getWorkbench()
							.getActiveWorkbenchWindow().getActivePage();
					KanjiEditorInput input = new KanjiEditorInput(kanji
							.getKanjiId());
					IEditorPart editor = page.findEditor(input);
					if (editor != null && editor instanceof KanjiEditor) {
						page.activate(editor);
					} else {
						page.openEditor(input, KanjiEditor.ID);
					}

				} catch (Exception ex) {
					throw new RuntimeException(KanjiEditor.ID);
				}
			}
		});
	}

	public static void sentencesHookDoubleClickCommand(
			final CommonServices commonServices, final TableViewer tblViewer) {
		tblViewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				IStructuredSelection selection = (IStructuredSelection) tblViewer
						.getSelection();
				if (selection != null && selection.getFirstElement() instanceof Sentence) {
					Sentence sentence = (Sentence) selection.getFirstElement();
					AddSentenceWizard newSentenceWizard = new AddSentenceWizard(
							commonServices, sentence);
					WizardDialog dialog = new WizardDialog(tblViewer.getTable()
							.getShell(), newSentenceWizard);
					dialog.open();
				}
			}
		});

	}

	public static void grammarsHookDoubleClickCommand(
			final TableViewer tableViewer) {
		tableViewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				try {
					IStructuredSelection selection = (IStructuredSelection) tableViewer
							.getSelection();
					Grammar grammar = (Grammar) selection.getFirstElement();
					IWorkbenchPage page = PlatformUI.getWorkbench()
							.getActiveWorkbenchWindow().getActivePage();
					GrammarEditorInput input = new GrammarEditorInput(grammar
							.getGrammarId());
					IEditorPart editor = page.findEditor(input);
					if (editor != null && editor instanceof GrammarEditor) {
						page.activate(editor);
					} else {
						page.openEditor(input, GrammarEditor.ID);
					}

				} catch (Exception ex) {
					throw new RuntimeException(GrammarEditor.ID);
				}
			}
		});
	}

	public static void executeACommand(String commandId, HashMap params,
			Object trigger) {
		ICommandService cs = (ICommandService) PlatformUI.getWorkbench()
				.getActiveWorkbenchWindow().getService(ICommandService.class);
		Command cmd = cs.getCommand(NewVocabulary.ID);
		IEvaluationService evaluationService = (IEvaluationService) PlatformUI
				.getWorkbench().getActiveWorkbenchWindow()
				.getService(IEvaluationService.class);
		IEvaluationContext currentState = evaluationService.getCurrentState();
		try {
			cmd.executeWithChecks(new ExecutionEvent(cmd, params, trigger,
					currentState));
		} catch (ExecutionException e) {
			e.printStackTrace();
		} catch (NotDefinedException e) {
			e.printStackTrace();
		} catch (NotEnabledException e) {
			e.printStackTrace();
		} catch (NotHandledException e) {
			e.printStackTrace();
		}
	}

	public static void changeTableRowHeigh(Table table, final int heigh) {
		table.addListener(SWT.MeasureItem, new Listener() {
			@Override
			public void handleEvent(Event event) {
				event.height = heigh;
			}

		});
	}

	public static void changeTableRowHeigh(Table table) {
		changeTableRowHeigh(table, TABLE_ROW_HEIGH_DEFAULT);
	}
	
	public static Set<Grammar> getSelectedGrammars(IStructuredSelection selection){
		Set<Grammar> selectedGrammars = new HashSet<Grammar>();
		for(Iterator<Grammar> iter = selection.iterator(); iter.hasNext();){
			selectedGrammars.add(iter.next());
		}
		
		return selectedGrammars;
	}
	
	public static Set<Sentence> getSelectedSentences(IStructuredSelection selection){
		Set<Sentence> selectedSentences = new HashSet<Sentence>();
		for(Iterator<Sentence> iter = selection.iterator(); iter.hasNext();){
			selectedSentences.add(iter.next());
		}
		
		return selectedSentences;
	}
	
	public static Set<Kanji> getSelectedKanjis(IStructuredSelection selection){
		Set<Kanji> selectedKanjis = new HashSet<Kanji>();
		for(Iterator<Kanji> iter = selection.iterator(); iter.hasNext();){
			selectedKanjis.add(iter.next());
		}
		
		return selectedKanjis;
	}
	
	public static Set<Vocabulary> getSelectedVocabularies(IStructuredSelection selection){
		Set<Vocabulary> selectedVocabularies = new HashSet<Vocabulary>();
		for(Iterator<Vocabulary> iter = selection.iterator(); iter.hasNext();){
			selectedVocabularies.add(iter.next());
		}
		
		return selectedVocabularies;
	}

}
